﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace St0rm.IRCPro.Client {
    /// <summary>
    /// Represents a users access to a channel
    /// </summary>
    public class ChannelAccess {
        private string _prefixes = "";
        private Client _client;

        /// <summary>
        /// Client associated with this channel access
        /// </summary>
        public Client Client {
            get {
                return _client;
            }
        }

        /// <summary>
        /// Prefixes associated with this channel access. Can be empty for no prefix
        /// </summary>
        public string Prefix {
            get {
                return _prefixes;
            }
        }

        /// <summary>
        /// Returns the most important prefix in the list of prefixes. can be '\0' for no modes
        /// </summary>
        public char HeadPrefix
        {
            get
            {
                if (String.IsNullOrEmpty(_prefixes))
                    return '\0';

                else
                    return _prefixes[0];
            }
        }

        /// <summary>
        /// Highest mode set on user to grant this access. Can be '\0' for no mode
        /// </summary>
        public char Mode 
        {
            get 
            {
                if (String.IsNullOrEmpty(_prefixes))
                    return '\0';
                return Client.Server.GetModeByPrefix(_prefixes[0]);
            }
        }

        /// <summary>
        /// Returns all modes set on this user (that has been seen). Empty string if none.
        /// </summary>
        public string Modes
        {
            get
            {
                StringBuilder sb = new StringBuilder();
                
                foreach (char c in _prefixes)
                {
                    char mode = Client.Server.GetModeByPrefix(c);
                    if (mode != '\0')
                       sb.Append(mode);
                }
                return sb.ToString();
            }
        }

        /// <summary>
        /// Integer representation of level based on prefix position in PREFIX. Op is 2 with op and voice, and 3 with owner protect op halfop voice.
        /// </summary>
        public int Level
        {
            get
            {
                if (String.IsNullOrEmpty(_prefixes))
                    return 0;

                int i = 0;
                foreach (char c in Client.Server.Prefixes)
                {
                    if (c == _prefixes[0])
                        return Client.Server.Prefixes.Count() - i;
                    i++;
                }
                return 0;
            }
        }

        /// <summary>
        /// Constructs a new channel access representation given a list of prefixes and the client
        /// </summary>
        /// <param name="prefixes">Prefixes a user has in order of highest value to lowest</param>
        /// <param name="client">Client user is on</param>
        public ChannelAccess(string prefixes, Client client) {
            _client = client;
            _prefixes = prefixes;
        }

        /// <summary>
        /// Removes one mode from this access
        /// </summary>
        /// <param name="mode"></param>
        public void RemoveMode(char mode)
        {
            char prefix = Client.Server.GetPrefixByMode(mode);
            if (_prefixes.Contains(prefix))
            {
                _prefixes = _prefixes.Replace(prefix.ToString(), "");
            }
                
        }

        /// <summary>
        /// Adds one mode to this access
        /// </summary>
        /// <param name="mode"></param>
        public void AddMode(char mode)
        {
            char prefix = Client.Server.GetPrefixByMode(mode);
            if (!_prefixes.Contains(prefix))
            {
                char[] prefixarray = new char[_prefixes.Length + 1];

                Array.Copy(_prefixes.ToCharArray(), prefixarray, _prefixes.Length);
                prefixarray[prefixarray.Length - 1] = Client.Server.GetPrefixByMode(mode);

                char[] serverPrefixes = Client.Server.Prefixes;
                Array.Sort<char>(prefixarray, new Comparison<char>( (c1, c2) => {
                    if (c1 == c2)
                        return 0;

                    int pos1 = 0, pos2 = 0, i = 0 ;
                    foreach (char c in serverPrefixes)
                    {
                        if (c == c1)
                            pos1 = i;
                        else if (c == c2)
                            pos2 = i;
                        i++;
                    }

                    if (pos1 > pos2)
                        return 1;
                    else
                        return -1;


                } ));

                _prefixes = new String(prefixarray);


            }
        }

    }
}
